<template>
  <div></div>
</template>

<script>
import * as THREE from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min'

export default {
  name: 'ThirteenFour',
  data() {
    return {
      box: null,                   // 立方体对象
    }
  },
  mounted() {
    this.initScene();
    this.initCamera();
    this.initRenderer();
    this.addBoxGeometry(3, 4, 2, 3, 4, 2);
    this.addOrbitControls();
    this.animation();
    this.initControl();
  },
  methods: {
    // 初始化场景
    initScene() {
      this.scene = new THREE.Scene();
    },
    // 初始化相机
    initCamera() {
      // 创建一个相机 视点
      this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
      // 设置相机的位置
      this.camera.position.x = 3;
      this.camera.position.y = 3;
      this.camera.position.z = 3;
      this.camera.lookAt(0, 0, 0);
    },
    // 初始化渲染器
    initRenderer() {
      // 创建一个渲染器
      this.renderer = new THREE.WebGLRenderer();
      // 设置渲染器尺寸
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(this.renderer.domElement);
    },
    // 添加一个立方体
    addBoxGeometry(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) {
      const boxGeometry = new THREE.BoxGeometry(width, height, depth, widthSegments, heightSegments, depthSegments);
      const boxMaterial = new THREE.MeshBasicMaterial({ color: 0x0000ff });
      boxMaterial.side = THREE.DoubleSide;
      boxMaterial.wireframe = true;
      this.box = new THREE.Mesh(boxGeometry, boxMaterial);
      this.scene.add(this.box);
    },
    // 添加轨道控制器
    addOrbitControls() {
      this.orbitControls = new OrbitControls(this.camera, this.renderer.domElement);
      // 设置带阻尼的惯性
      this.orbitControls.enableDamping = true;
      // 设置阻尼系数
      this.orbitControls.dampingFactor = 0.05;
    },
    // 动画函数
    animation() {
      this.orbitControls.update();
      // 渲染
      this.renderer.render(this.scene, this.camera);
      requestAnimationFrame(this.animation);
    },
    // 初始化lil.gui调试工具
    initControl() {
      const gui = new GUI();

      const params = {
        width: this.box.geometry.parameters.width,
        height: this.box.geometry.parameters.height,
        depth: this.box.geometry.parameters.depth,
        widthSegments: this.box.geometry.parameters.widthSegments,
        heightSegments: this.box.geometry.parameters.heightSegments,
        depthSegments: this.box.geometry.parameters.depthSegments,
      }

      let folder = gui.addFolder('立方几何体属性');
      folder.add(params, 'width', 1, 10).step(0.1).name('width-宽度').onChange(width => {
        params.width = width;
        this.scene.remove(this.box);
        this.addBoxGeometry(params.width, params.height, params.depth, params.widthSegments, params.heightSegments, params.depthSegments);
      });
      folder.add(params, 'height', 1, 10).step(0.1).name('height-高度').onChange(height => {
        params.height = height;
        this.scene.remove(this.box);
        this.addBoxGeometry(params.width, params.height, params.depth, params.widthSegments, params.heightSegments, params.depthSegments);
      })
      folder.add(params, 'depth', 1, 10).step(0.1).name('depth-深度').onChange(depth => {
        params.depth = depth;
        this.scene.remove(this.box);
        this.addBoxGeometry(params.width, params.height, params.depth, params.widthSegments, params.heightSegments, params.depthSegments);
      });
      folder.add(params, 'widthSegments', 1, 10).step(1).name('widthSegments-宽度分段数').onChange(widthSegments => {
        params.widthSegments = widthSegments;
        this.scene.remove(this.box);
        this.addBoxGeometry(params.width, params.height, params.depth, params.widthSegments, params.heightSegments, params.depthSegments);
      })
      folder.add(params, 'heightSegments', 1, 10).step(1).name('heightSegments-高度分段数').onChange(heightSegments => {
        params.heightSegments = heightSegments;
        this.scene.remove(this.box);
        this.addBoxGeometry(params.width, params.height, params.depth, params.widthSegments, params.heightSegments, params.depthSegments);
      });
      folder.add(params, 'depthSegments', 1, 10).step(1).name('depthSegments-深度分段数').onChange(depthSegments => {
        params.depthSegments = depthSegments;
        this.scene.remove(this.box);
        this.addBoxGeometry(params.width, params.height, params.depth, params.widthSegments, params.heightSegments, params.depthSegments);
      })
    }
  }
}
</script>

<style scoped>

</style>
